
#pragma once

#include <vector>
#include <map>
#include <list>

#include "crparser.h"

#include "shared_ptr.h"


class CRPARSER_API CRVertex {

public:
	virtual ~CRVertex();

public:
	enum Type {
		FUNCTION, GLOBAL_VAR
	};

	virtual Type type() const = 0;

private:
	CRVertex(const CRVertex &);
	const CRVertex &operator = (const CRVertex &);
};


class CRPARSER_API CREdge {

private:
	CREdge();

public:
	enum Type {
		NONE, CALL, READ, WRITE
	};
};


struct CRPARSER_API CRAdjacentVertex {
	size_t Vertex;
	CREdge::Type Relation;

	CRAdjacentVertex() : Vertex((size_t) -1), Relation(CREdge::NONE) {}
	CRAdjacentVertex(size_t vertex, CREdge::Type relation) : Vertex(vertex), Relation(relation) {}
};

typedef std::vector<shared_ptr<CRVertex> > CRVertexList;
typedef std::list<CRAdjacentVertex> CRAdjacentVertexList;
typedef std::map<shared_ptr<CRVertex>, CRAdjacentVertexList> CRAdjacentMap;


class CRPARSER_API CRGraph {

public:
	const CRVertexList &vertices() const;
	bool hasAdjacents(shared_ptr<CRVertex> vertex) const;

	size_t addVertex(shared_ptr<CRVertex> vertex);
	void addAdjacentVertex(shared_ptr<CRVertex> vertex, CRAdjacentVertex adjacent);

private:
	CRVertexList myVertices;
	CRAdjacentMap myEdges;

private:
	CRGraph(const CRGraph &);
	const CRGraph &operator = (const CRGraph &);
};

inline const CRVertexList &CRGraph::vertices() const { return myVertices; }


class CRPARSER_API CRParser {

private:
	CRParser();
	static shared_ptr<CRParser> ourInstance;

public:
	static CRParser &Instance();

public:
	bool parseSourceFile(const std::string &fileName, CRGraph& graph);

private:
	CRParser(const CRParser &);
	const CRParser &operator = (const CRParser &);
};
